"""
商品价格分析业务逻辑模块
"""
from typing import Dict, List, Optional, Tuple
from reqapi.get_commodity_trend import GetCommodityTrendApi
from reqapi.get_template_info import GetTemplateInfoApi, ExteriorItem
from biz.kmeans_price_analyzer import ItemPricingStrategy
import numpy as np
import statistics
import time
import random
import json
from com.db.task_manager import TaskManager
from com.db.history_data_manager import HistoryDataManager

class PriceAnalyzer:
    """价格分析器类"""
    
    def __init__(self):
        # 定义外观类型
        self.exteriors = {
            'FN': '崭新出厂',
            'MW': '略有磨损',
            'FT': '久经沙场',
            'WW': '破损不堪',
            'BS': '战痕累累'
        }
        
        # 定义每个外观的磨损值范围（仅作为参考信息）
        self.wear_ranges = {
            'FN': (0.00, 0.07),
            'MW': (0.07, 0.15),
            'FT': (0.15, 0.38),
            'WW': (0.38, 0.45),
            'BS': (0.45, 1.00)
        }
        
        # 创建任务管理器实例
        self.task_manager = TaskManager()
        
    def random_sleep(self):
        """随机等待0.5-4秒"""
        sleep_time = random.uniform(0.2, 2)
        print(f"随机等待 {sleep_time:.1f} 秒...")
        time.sleep(sleep_time)
        
    def get_all_exterior_history(self, template_id: int, api_client: GetCommodityTrendApi, template_api: GetTemplateInfoApi) -> Dict[str, Dict[str, List]]:
        """获取所有外观的历史数据
        
        Args:
            template_id: 商品模板ID
            api_client: API客户端实例
            template_api: 模板API客户端实例
            
        Returns:
            Dict[str, Dict[str, List]]: 按外观分组的历史数据
                {
                    "exterior_name": {
                        "template_id": "xxx",
                        "uu_history": [...],
                        "steam_history": [...],
                        "listing_history": [...]
                    }
                }
        """
        # 获取所有外观信息
        self.random_sleep()  # 随机等待
        exterior_items = template_api.get_exterior_items(template_id)
        if not exterior_items:
            print(f"获取外观信息失败: template_id={template_id}")
            return {}
            
        # 过滤掉已经存在于任务表中的饰品
        filtered_exterior_items = []
        for item in exterior_items:
            if not self.task_manager.get_task_by_goods_id(item.FixedVal):  # 使用点号访问属性
                filtered_exterior_items.append(item)
        
        if not filtered_exterior_items:
            print(f"所有外观都已存在于任务表中: template_id={template_id}")
            return {}
            
        # 存储所有外观的历史数据
        all_history = {}
        
        # 遍历每个外观
        for item in filtered_exterior_items:
            # 跳过StatTrak™类型
            if item.Name not in [
                "崭新出厂",
                "略有磨损",
                "久经沙场",
                "破损不堪",
                "战痕累累"
            ]:
                continue
                
            # 获取该外观的模板ID
            exterior_template_id = item.FixedVal
            
            # 获取三种历史数据
            self.random_sleep()  # 随机等待
            uu_result = api_client.execute(
                template_id=exterior_template_id,
                day=7,
                order_type=1  # UU价格
            )
            
            self.random_sleep()  # 随机等待
            steam_result = api_client.execute(
                template_id=exterior_template_id,
                day=7,
                order_type=13  # Steam价格
            )
            
            self.random_sleep()  # 随机等待
            listing_result = api_client.execute(
                template_id=exterior_template_id,
                day=7,
                order_type=11  # 在售数量
            )
            
            # 检查API返回结果
            if not uu_result or 'trade_list' not in uu_result:
                print(f"获取UU历史数据失败: template_id={exterior_template_id}")
                continue
                
            if not steam_result or 'trade_list' not in steam_result:
                print(f"获取Steam历史数据失败: template_id={exterior_template_id}")
                continue
                
            if not listing_result or 'trade_list' not in listing_result:
                print(f"获取在售数量数据失败: template_id={exterior_template_id}")
                continue
            
            # 存储该外观的所有数据
            all_history[item.Name] = {
                "template_id": exterior_template_id,
                "uu_history": uu_result['trade_list'],
                "steam_history": steam_result['trade_list'],
                "listing_history": listing_result['trade_list']
            }
            
        return all_history

    def analyze_all_exteriors(self, all_history: Dict[str, Dict[str, List]]) -> Dict[str, Dict]:
        """分析所有外观的价格数据
        
        Args:
            all_history: 所有外观的历史数据
            
        Returns:
            Dict[str, Dict]: 每个外观的分析结果
        """
        results = {}
        
        # 外观名称到代号的映射
        name_to_code = {
            "崭新出厂": "FN",
            "略有磨损": "MW",
            "久经沙场": "FT",
            "破损不堪": "WW",
            "战痕累累": "BS"
        }
        
        for exterior_name, history_data in all_history.items():
            # 获取外观代号
            exterior_code = name_to_code.get(exterior_name)
            if not exterior_code:
                continue
                
            # 计算该外观的建议价格
            analysis = self.calculate_suggested_price(
                history_data['uu_history'],
                history_data['steam_history'],
                history_data['listing_history'],
                exterior=exterior_code  # 使用正确的外观代号
            )
            
            if analysis:
                results[exterior_name] = analysis
                
        return results

    def calculate_suggested_price(self, uu_history: List[Dict], steam_history: List[Dict], listing_history: List[Dict], exterior: str = "MW") -> Dict:
        """计算建议购买价格
        
        Args:
            uu_history: UU历史价格数据
            steam_history: Steam历史价格数据
            listing_history: 在售商品数据
            exterior: 外观代号，默认为略有磨损(MW)
            
        Returns:
            Dict: 分析结果
        """
        if not uu_history or not steam_history:
            return None
            
        # 获取磨损值范围
        wear_ranges = {
            "FN": (0.000, 0.070),
            "MW": (0.070, 0.150),
            "FT": (0.150, 0.380),
            "WW": (0.380, 0.450),
            "BS": (0.450, 1.000)
        }
        wear_min, wear_max = wear_ranges.get(exterior, (0.070, 0.150))
            
        # 计算UU平均价格
        uu_prices = [float(record['price']) for record in uu_history]
        uu_avg_price = sum(uu_prices) / len(uu_prices)
        
        # 计算Steam平均价格
        steam_prices = [float(record['price']) for record in steam_history]
        steam_avg_price = sum(steam_prices) / len(steam_prices) if steam_prices else 0
        
        # 获取当前UU价格
        current_uu_price = float(uu_history[0]['price']) if uu_history else 0
        
        # 计算建议购买价格 (UU平均价格的95%)
        suggested_price = round(uu_avg_price * 0.95, 2)
        
        # 计算相对UU均价的折扣
        discount = round((current_uu_price - uu_avg_price) / uu_avg_price * 100, 1)
        
        # 计算Steam价格溢价
        steam_premium = round((steam_avg_price - uu_avg_price) / uu_avg_price * 100, 1)
        
        # 分析价格趋势
        price_trend = "稳定"
        price_change = 0
        if len(uu_prices) >= 2:
            recent_avg = sum(uu_prices[:10]) / min(10, len(uu_prices))
            old_avg = sum(uu_prices[-10:]) / min(10, len(uu_prices))
            price_change = round((recent_avg - old_avg) / old_avg * 100, 1)
            if abs(price_change) > 10:
                price_trend = f"{'上涨' if price_change > 0 else '下跌'}"
        
        # 分析供应状况
        current_supply = int(float(listing_history[0]['price'])) if listing_history else 0
        supply_status = "稳定"
        if current_supply < 50:
            supply_status = "减少，价格可能上涨"
        elif current_supply > 1000:
            supply_status = "充足，价格可能下跌"
            
        # 生成购买建议
        if price_change > 10 and current_supply < 100:
            buy_suggestion = "👍 建议购入：价格可能继续上涨"
        elif price_change < -10:
            buy_suggestion = "⚠️ 建议观望：价格可能继续下跌"
        else:
            buy_suggestion = "👉 可以考虑购入，但需要观察市场变化"
            
        # 生成补充说明
        if current_uu_price < suggested_price:
            price_note = f"当前价格{current_uu_price:.2f}低于建议价格{suggested_price}，可以考虑直接购买"
        else:
            price_note = f"建议以{suggested_price}的价格挂单购买，当前价格{current_uu_price:.2f}略高"
            
        # 获取外观中文名称
        exterior_names = {
            "FN": "崭新出厂",
            "MW": "略有磨损",
            "FT": "久经沙场",
            "WW": "破损不堪",
            "BS": "战痕累累"
        }
        
        return {
            "exterior": exterior_names.get(exterior, "未知"),  # 外观名称
            "wear_range": f"{wear_min:.3f} - {wear_max:.3f}",  # 磨损值范围
            "suggested_price": suggested_price,  # 建议购买价格
            "current_price": current_uu_price,  # 当前价格
            "discount": discount,  # 相对UU均价的折扣
            "price_trend": {
                "status": price_trend,  # 价格趋势
                "change": price_change  # 价格变化率
            } if price_change != 0 else {"status": price_trend},
            "supply": {
                "status": supply_status,  # 供应状况
                "count": current_supply  # 在售数量
            },
            "steam_premium": steam_premium,  # Steam价格溢价
            "buy_suggestion": buy_suggestion,  # 购买建议
            "price_note": price_note,  # 补充说明
            "data_stats": {
                "uu_history_count": len(uu_history),  # UU历史价格数据数量
                "steam_history_count": len(steam_history),  # Steam历史价格数据数量
                "listing_count": len(listing_history)  # 在售商品数据数量
            }
        }

    def get_price_suggestion_advice(self, price_analysis):
        """根据价格分析给出建议"""
        if not price_analysis:
            return "数据不足，无法给出建议"
            
        advice = []
        
        # 1. 基本价格信息
        suggested_price = price_analysis['suggested_price']
        current_price = price_analysis['current_price']
        discount = price_analysis['discount']
        exterior = price_analysis['exterior']
        wear_range = price_analysis['wear_range']
        
        advice.append(f"外观：{exterior}")
        advice.append(f"磨损值范围：{wear_range}")
        advice.append(f"建议购买价格: {suggested_price:.2f}")
        advice.append(f"当前价格: {current_price:.2f}")
        advice.append(f"相对当前价格折扣: {discount:.1f}%")
        
        # 2. 价格趋势分析
        price_trend = price_analysis['price_trend']
        if 'change' in price_trend:
            advice.append(f"\n价格趋势：{price_trend['status']}，最近价格变化{price_trend['change']:.1f}%")
        else:
            advice.append(f"\n价格趋势：{price_trend['status']}")
            
        # 3. 供应分析
        supply_status = price_analysis['supply']['status']
        current_supply = price_analysis['supply']['count']
        
        advice.append("\n供应状况：")
        advice.append(f"• {supply_status}")
        advice.append(f"• 当前在售数量：{current_supply:.0f}")
        
        # 4. Steam价格对比
        steam_premium = price_analysis['steam_premium']
        if steam_premium:
            advice.append(f"\nSteam价格对比：")
            advice.append(f"• Steam价格相对于UU价格溢价{steam_premium:.1f}%")
        
        # 5. 购买建议
        advice.append("\n购买建议：")
        advice.append(price_analysis['buy_suggestion'])
        
        # 6. 补充说明
        advice.append("\n补充说明：")
        advice.append(price_analysis['price_note'])
        
        advice.append("\n⚠️ 注意：")
        advice.append(f"1. 以上分析基于{exterior}外观的历史交易数据")
        advice.append(f"2. 该外观的磨损值范围为：{wear_range}")
        advice.append("3. 具体成交价格可能因磨损值不同而有较大差异")
        advice.append("4. 建议购买前查看具体商品的磨损值")
        
        return "\n".join(advice)

    def analyze_investment_value(self, all_history: Dict[str, Dict[str, List]], min_supply: int = 300) -> Dict:
        """分析投资价值
        
        Args:
            all_history: 所有外观的历史数据
            min_supply: 最小在售数量要求，用于评分计算，默认300
            
        Returns:
            Dict: 分析结果
        """
        base_analysis = {}
        
        # 1. 计算每个外观的基础指标
        for exterior_name, history_data in all_history.items():
            uu_history = history_data['uu_history']
            steam_history = history_data['steam_history']
            listing_history = history_data['listing_history']
            
            if not uu_history:
                continue
                
            
            # 提取价格数据
            prices = [float(record['price']) for record in uu_history]
            current_price = prices[0]
            avg_price = sum(prices) / len(prices)
            
            # 计算流动性指标
            daily_volume = len(uu_history) / 7  # 假设是7天的数据
            
            # 获取当前外观的在售数量 - 使用最新的在售数量数据
            supply = float(listing_history[0]['price']) if listing_history else 0
            
            print(f"\n{exterior_name}的在售数量: {supply}")  # 调试信息
            
            # 计算供需评分时，同时考虑在售数量和供需比
            # 先计算在售数量的评分（在售量越大分数越高）
            supply_volume_score = min(supply / min_supply * 100, 100)  # 在售量评分，最高100分
            
            print(f"在售量评分: {supply_volume_score:.1f} (在售量: {supply}, 基准: {min_supply})")  # 调试信息
            
            # 计算供需比评分（维持原有逻辑，供需比合理时分数高）
            supply_demand_ratio = supply / (daily_volume if daily_volume > 0 else 1)
            supply_ratio_score = 100 / (1 + supply_demand_ratio)
            
            print(f"供需比评分: {supply_ratio_score:.1f} (供需比: {supply_demand_ratio:.1f})")  # 调试信息
            
            # 综合供需评分（总计100分）
            supply_score = supply_volume_score * 0.6 + supply_ratio_score * 0.4
            
            print(f"综合供需评分: {supply_score:.1f}")  # 调试信息
            
            # 计算价格波动率
            price_std = np.std(prices) if len(prices) > 1 else 0
            price_volatility = (price_std / avg_price) if avg_price > 0 else 0
            
            # 计算价格趋势
            price_trend = ((current_price - prices[-1]) / prices[-1]) if len(prices) > 1 else 0
            
            # 计算Steam溢价
            steam_prices = [float(record['price']) for record in steam_history]
            steam_avg = sum(steam_prices) / len(steam_prices) if steam_prices else 0
            steam_premium = ((steam_avg - avg_price) / avg_price) if avg_price > 0 else 0
            
            base_analysis[exterior_name] = {
                'current_price': current_price,  # 当前价格
                'avg_price': avg_price,  # 平均价格
                'daily_volume': daily_volume,  # 日均成交量
                'supply': supply,  # 在售数量
                'supply_demand_ratio': supply_demand_ratio,  # 供需比
                'supply_volume_score': supply_volume_score,  # 在售量评分
                'supply_ratio_score': supply_ratio_score,  # 供需比评分
                'supply_score': supply_score,  # 综合供需评分
                'price_volatility': price_volatility,  # 价格波动率
                'price_trend': price_trend,  # 价格趋势
                'steam_premium': steam_premium,  # Steam溢价
                'suggested_price': current_price,  # 建议价格
                'template_id': all_history[exterior_name]['template_id']  # 商品模板ID
            }
            
        if not base_analysis:
            return {}
            
        # 2. 计算外观间价格相关性
        fn_prices = [float(record['price']) for record in all_history['崭新出厂']['uu_history']] if '崭新出厂' in all_history else []
        
        for i, wear_type in enumerate(["崭新出厂", "略有磨损", "久经沙场", "破损不堪", "战痕累累"]):
            if wear_type not in all_history:
                continue
                
            history = all_history[wear_type]
            
            # 计算2天和7天的价格数据
            recent_2d = []
            recent_7d = []
            
            current_time = time.time()
            two_days_ago = current_time - 2 * 24 * 3600
            
            for record in history['uu_history']:
                try:
                    price = float(record['price'])
                    record_time = float(record['time'])
                    
                    if record_time >= two_days_ago:
                        recent_2d.append(price)
                    recent_7d.append(price)
                except (ValueError, KeyError):
                    continue
            
            if not recent_7d:
                continue
                
            # 计算统计数据
            stats = {
                'recent_2d': {
                    'max': max(recent_2d) if recent_2d else None,
                    'mean': statistics.mean(recent_2d) if recent_2d else None,
                    'std': statistics.stdev(recent_2d) if len(recent_2d) > 1 else 0
                },
                'recent_7d': {
                    'max': max(recent_7d),
                    'mean': statistics.mean(recent_7d),
                    'std': statistics.stdev(recent_7d) if len(recent_7d) > 1 else 0
                }
            }
            
            # 计算波动率
            volatility_7d = stats['recent_7d']['std'] / stats['recent_7d']['mean'] if stats['recent_7d']['mean'] > 0 else 0
            
            # 价格连续性（与上一个外观比较）
            if i > 0:
                prev_wear = ["崭新出厂", "略有磨损", "久经沙场", "破损不堪", "战痕累累"][i-1]
                if prev_wear in all_history:
                    prev_history = all_history[prev_wear]
                    prev_prices = [float(r['price']) for r in prev_history['uu_history']]
                    if prev_prices:
                        price_ratio = stats['recent_7d']['mean'] / statistics.mean(prev_prices)
                    else:
                        price_ratio = None
                else:
                    price_ratio = None
            else:
                price_ratio = None
            
            price_analysis = {
                wear_type: {
                    'stats': stats,
                    'volatility_7d': volatility_7d,
                    'price_ratio': price_ratio
                }
            }
            
        # 4. 计算投资评分
        max_volume = max((data['daily_volume'] for data in base_analysis.values()), default=0)
        max_premium = max((data['steam_premium'] for data in base_analysis.values()), default=0)
        
        for exterior_name, data in base_analysis.items():
            # 流动性评分 (0-100)
            liquidity_score = (data['daily_volume'] / max_volume) * 100 if max_volume > 0 else 0
            
            # 价格优势评分 (0-100)
            # 1. Steam溢价评分
            steam_premium_score = (data['steam_premium'] / max_premium) * 100 if max_premium > 0 else 0
            
            # 2. 价格趋势评分
            trend_score = min(data['price_trend'] * 100, 100) if data['price_trend'] > 0 else 0
            
            # 3. 当前价格与均价比较评分
            price_vs_avg = (data['avg_price'] - data['current_price']) / data['avg_price'] if data['avg_price'] > 0 else 0
            price_vs_avg_score = min(price_vs_avg * 100, 100) if price_vs_avg > 0 else 0
            
            # 综合价格优势评分（总计100分）
            price_advantage_score = (
                steam_premium_score * 0.1 +    # Steam溢价权重10%
                trend_score * 0.45 +           # 价格趋势权重45%
                price_vs_avg_score * 0.45      # 均价比较权重45%
            )
            
            # 稳定性评分 (0-100)
            stability_score = (1 - data['price_volatility']) * 100
            
            # 供需评分 (0-100)
            supply_score = data['supply_score']  # 使用新的供需评分
            
            # 综合评分 (0-100)
            investment_score = (
                liquidity_score * 0.25 +      # 流动性权重25%
                price_advantage_score * 0.15 + # 价格优势权重15%
                stability_score * 0.25 +       # 稳定性权重25%
                supply_score * 0.35           # 供需关系权重35%
            )
            
            # 保存各项评分到结果中
            data['investment_score'] = investment_score  # 投资评分
            data['liquidity_score'] = liquidity_score  # 流动性评分
            data['price_advantage_score'] = price_advantage_score  # 价格优势评分
            data['steam_premium_score'] = steam_premium_score  # Steam溢价评分
            data['trend_score'] = trend_score  # 价格趋势评分
            data['price_vs_avg_score'] = price_vs_avg_score  # 均价比较评分
            data['stability_score'] = stability_score  # 稳定性评分
            data['supply_score'] = supply_score  # 供需评分
            data['template_id'] = all_history[exterior_name]['template_id']  # 商品模板ID
            
        return base_analysis

    def get_investment_advice(self, analysis_results: Dict) -> str:
        """生成投资建议
        
        Args:
            analysis_results: 分析结果
            
        Returns:
            str: 投资建议
        """
        advice = []
        
        # 1. 整体投资价值评估
        avg_score = sum(data['investment_score'] for data in analysis_results.values()) / len(analysis_results)
        
        advice.append("=== 饰品整体投资价值评估 ===\n")
        if avg_score >= 70:
            advice.append("✨ 该饰品具有较高的投资价值，建议关注")
        elif avg_score >= 50:
            advice.append("🔍 该饰品具有一定投资价值，建议择机介入")
        else:
            advice.append("⚠️ 该饰品投资价值一般，建议观望")
            
        # 2. 各外观投资价值排名
        advice.append("\n=== 投资建议 ===\n")
        
        # 按投资评分排序
        ranked_exteriors = sorted(
            analysis_results.items(),
            key=lambda x: (x[1]['investment_score'], -x[1].get('volatility', 0)),  # 优先按投资评分排序，同分按波动率低的优先
            reverse=True
        )
        
        # 获取前三名且在售量达到最小要求的外观
        top_exteriors = []
        for exterior_name, data in ranked_exteriors:
            if len(top_exteriors) >= 3:  # 最多取前三名
                break
                
            # 检查在售量是否达到最小要求
            supply = data['supply']
            if supply >= 300:  # 使用300作为最小销售数量要求
                top_exteriors.append((exterior_name, data))
        
        if not top_exteriors:
            advice.append("❗ 暂无符合条件的外观（评分前三且在售量达到最小要求）")
        else:
            advice.append("🌟 推荐关注以下外观（评分前三且在售量达到最小要求）：\n")
            
            for i, (exterior_name, data) in enumerate(top_exteriors, 1):
                score = data['investment_score']
                advice.append(f"\n{i}. {exterior_name} - 评分: {score:.1f}")
                
                # 流动性评分 (0-100)
                liquidity_score = data['liquidity_score']
                advice.append(f"  - 流动性评分(25%): {liquidity_score:.1f} (日均成交: {data['daily_volume']:.1f})")
                
                # 价格优势评分 (0-100)
                price_advantage_score = data['price_advantage_score']
                advice.append(f"  - 价格优势评分(15%): {price_advantage_score:.1f}")
                advice.append(f"    • Steam溢价(10%): {data['steam_premium_score']:.1f} (溢价率: {data['steam_premium']*100:.1f}%)")
                advice.append(f"    • 价格趋势(45%): {data['trend_score']:.1f} (趋势: {data['price_trend']*100:+.1f}%)")
                advice.append(f"    • 均价比较(45%): {data['price_vs_avg_score']:.1f} (低于均价: {(data['avg_price']-data['current_price'])/data['avg_price']*100:.1f}%)")
                
                # 稳定性评分 (0-100)
                stability_score = data['stability_score']
                advice.append(f"  - 稳定性评分(25%): {stability_score:.1f} (波动率: {data['price_volatility']*100:.1f}%)")
                
                # 供需评分 (0-100)
                supply_score = data['supply_score']
                advice.append(f"  - 供需评分(35%): {supply_score:.1f} (在售量评分: {data['supply_volume_score']:.1f}, 供需比评分: {data['supply_ratio_score']:.1f})")
                
                advice.append(f"  • 当前价格: {data['current_price']:.2f}")
                advice.append(f"  • 建议买入价格: {data['suggested_price']:.2f}")
                advice.append(f"  • 在售数量: {data['supply']:.0f}")
        
        return "\n".join(advice)

    def analyze_price_continuity(self, all_history, wear_ranges):
        """分析价格连续性和波动率
        
        Args:
            all_history: 所有外观的历史数据
            wear_ranges: 外观磨损范围
            
        Returns:
            dict: 价格连续性分析结果
        """
        wear_order = [
            "崭新出厂",
            "略有磨损",
            "久经沙场",
            "破损不堪",
            "战痕累累"
        ]
        
        price_analysis = {}
        
        for i, wear_type in enumerate(wear_order):
            if wear_type not in all_history:
                continue
                
            history = all_history[wear_type]
            
            # 计算2天和7天的价格数据
            recent_2d = []
            recent_7d = []
            
            current_time = time.time()
            two_days_ago = current_time - 2 * 24 * 3600
            
            for record in history['uu_history']:
                try:
                    price = float(record['price'])
                    record_time = float(record['time'])
                    
                    if record_time >= two_days_ago:
                        recent_2d.append(price)
                    recent_7d.append(price)
                except (ValueError, KeyError):
                    continue
            
            if not recent_7d:
                continue
                
            # 计算统计数据
            stats = {
                'recent_2d': {
                    'max': max(recent_2d) if recent_2d else None,
                    'mean': statistics.mean(recent_2d) if recent_2d else None,
                    'std': statistics.stdev(recent_2d) if len(recent_2d) > 1 else 0
                },
                'recent_7d': {
                    'max': max(recent_7d),
                    'mean': statistics.mean(recent_7d),
                    'std': statistics.stdev(recent_7d) if len(recent_7d) > 1 else 0
                }
            }
            
            # 计算波动率
            volatility_7d = stats['recent_7d']['std'] / stats['recent_7d']['mean'] if stats['recent_7d']['mean'] > 0 else 0
            
            # 价格连续性（与上一个外观比较）
            if i > 0:
                prev_wear = wear_order[i-1]
                if prev_wear in all_history:
                    prev_history = all_history[prev_wear]
                    prev_prices = [float(r['price']) for r in prev_history['uu_history']]
                    if prev_prices:
                        price_ratio = stats['recent_7d']['mean'] / statistics.mean(prev_prices)
                    else:
                        price_ratio = None
                else:
                    price_ratio = None
            else:
                price_ratio = None
            
            price_analysis[wear_type] = {
                'stats': stats,
                'volatility_7d': volatility_7d,
                'price_ratio': price_ratio
            }
        
        return price_analysis
        
    def get_prev_exterior_max_price(self, wear_type, price_analysis):
        """获取上一个外观的最高正常价格
        
        Args:
            wear_type: 当前外观
            price_analysis: 价格分析结果
            
        Returns:
            float: 上一个外观的最高正常价格
        """
        wear_order = [
            "崭新出厂",
            "略有磨损",
            "久经沙场",
            "破损不堪",
            "战痕累累"
        ]
        
        try:
            current_index = wear_order.index(wear_type)
            if current_index == 0:  # 崭新出厂没有上一个外观
                return None
                
            prev_wear = wear_order[current_index - 1]
            if prev_wear not in price_analysis:
                return None
                
            prev_analysis = price_analysis[prev_wear]
            
            # 获取价格数据
            prices_7d = []
            if 'stats' in prev_analysis and 'recent_7d' in prev_analysis['stats']:
                if prev_analysis['stats']['recent_7d']['max'] is not None:
                    prices_7d = [prev_analysis['stats']['recent_7d']['max']]
                    
            if not prices_7d:
                return None
                
            # 由于已经在analyze_price_continuity中处理过异常值，这里直接使用
            return max(prices_7d)
            
        except (ValueError, IndexError, KeyError):
            return None
            
    def optimize_price_suggestion(self, wear_type, base_suggestion, price_analysis):
        """优化价格建议
        
        Args:
            wear_type: 外观类型
            base_suggestion: 原始价格建议
            price_analysis: 价格连续性分析结果
            
        Returns:
            dict: 优化后的价格建议
        """
        if wear_type not in price_analysis:
            return base_suggestion
            
        analysis = price_analysis[wear_type]
        volatility = analysis['volatility_7d']
        price_ratio = analysis.get('price_ratio')
        
        # 获取当前外观的历史最低价（排除异常值）
        current_lowest = None
        if 'stats' in analysis and 'recent_7d' in analysis['stats']:
            current_stats = analysis['stats']['recent_7d']
            if current_stats.get('mean') is not None and current_stats.get('std') is not None:
                mean = current_stats['mean']
                std = current_stats['std']
                # 波动率大时使用更保守的范围
                std_factor = 2 if volatility < 0.2 else 3
                current_lowest = mean - std_factor * std
        
        if current_lowest is None:
            current_lowest = base_suggestion['suggested_price'] * 0.8
            
        # 卖出价：历史最低价 * 0.95（保持悲观）
        suggested_sell_price = current_lowest * 0.95
        
        # 崭新出厂的定价策略
        if wear_type == "崭新出厂":
            # 买入价：不超过卖出价
            suggested_buy_price = min(
                current_lowest,  # 历史最低价
                base_suggestion['suggested_price'] * 0.8,  # 当前价格的80%
                suggested_sell_price * 0.9  # 不超过卖出价的90%
            )
            
            optimized_suggestion = base_suggestion.copy()
            optimized_suggestion.update({
                'optimized_buy_price': suggested_buy_price,  # 优化后的买入价格
                'optimized_sell_price': suggested_sell_price,  # 优化后的卖出价格
                'volatility': volatility,  # 价格波动率
                'lowest_normal_price': current_lowest,  # 历史最低价
                'risk_level': '低' if volatility < 0.1 else '中' if volatility < 0.2 else '高',  # 风险等级
                'price_continuity': '正常' if price_ratio is None else '偏高' if price_ratio > 1.1 else '偏低' if price_ratio < 0.9 else '正常'  # 价格连续性
            })
            return optimized_suggestion
            
        # 其他外观的定价策略
        prev_max_price = self.get_prev_exterior_max_price(wear_type, price_analysis)
        
        if prev_max_price is not None:
            # 买入价：上一个外观最高价 * 安全系数
            base_safety_factor = 0.95
            # 根据波动率和价格连续性调整安全系数
            if volatility >= 0.2:  # 高波动
                base_safety_factor -= 0.05
            if price_ratio is not None and price_ratio > 1.1:  # 价格偏高
                base_safety_factor -= 0.05
                
            safety_factor = base_safety_factor - min(volatility * 2, 0.1)  # 最低0.75
            suggested_buy_price = min(
                prev_max_price * safety_factor,
                suggested_sell_price * 0.9  # 不超过卖出价的90%
            )
            
            # 价格保护：如果建议价格异常，使用基础建议
            if suggested_buy_price > base_suggestion['suggested_price'] * 1.2:
                suggested_buy_price = min(
                    base_suggestion['suggested_price'],
                    suggested_sell_price * 0.9
                )
        else:
            # 无法获取上一个外观的价格，使用基础建议
            suggested_buy_price = min(
                base_suggestion['suggested_price'],
                suggested_sell_price * 0.9
            )
            safety_factor = None
        
        # 合并建议
        optimized_suggestion = base_suggestion.copy()
        optimized_suggestion.update({
            'optimized_buy_price': suggested_buy_price,  # 优化后的买入价格
            'optimized_sell_price': suggested_sell_price,  # 优化后的卖出价格
            'prev_max_price': prev_max_price,  # 上一个外观的最高价格
            'volatility': volatility,  # 价格波动率
            'lowest_normal_price': current_lowest,  # 历史最低价
            'safety_factor': safety_factor,  # 安全系数
            'risk_level': '低' if volatility < 0.1 else '中' if volatility < 0.2 else '高',  # 风险等级
            'price_continuity': '正常' if price_ratio is None else '偏高' if price_ratio > 1.1 else '偏低' if price_ratio < 0.9 else '正常'  # 价格连续性
        })
        
        return optimized_suggestion

    def analyze_investment_opportunity(self, template_id: int, device_info: dict, min_supply: int = 300, commodity_name: str = '') -> Dict:
        """分析投资机会，整合所有分析步骤
        
        Args:
            template_id: 商品模板ID
            device_info: 扫货用户信息，包含device_id, device_token, uk等
            min_supply: 最小在售数量要求，用于筛选推荐，默认300
            commodity_name: 商品名称，用于日志显示
            
        Returns:
            Dict: 投资分析结果，包含：
                - overall_score: float  # 整体评分（0-100）
                - overall_advice: str   # 整体建议文本
                - advice_text: str      # 详细的投资建议文本
                - recommendations: List[Dict]  # 推荐外观列表，每个外观包含：
                    - name: str               # 外观名称（如"崭新出厂"）
                    - score: float            # 投资评分（0-100）
                    - liquidity_score: float  # 流动性评分
                    - price_advantage_score: float  # 价格优势评分
                    - stability_score: float  # 稳定性评分
                    - supply_score: float     # 供需评分
                    - current_price: float    # 当前价格
                    - suggested_price: float  # 建议买入价格
                    - supply: int            # 在售数量
                    - daily_volume: float    # 日均成交量
                    - steam_premium: float   # Steam溢价率
                    - price_trend: str       # 价格趋势（上涨/下跌/震荡）
                    - price_vs_avg: float    # 当前价格相对均价的偏离率
                    - volatility: float      # 价格波动率
                    - template_id: int       # 商品模板ID
                    - price_analysis: Dict   # K-means价格分析结果，包含：
                        - cluster_centers: List[float]  # 价格聚类中心点
                        - optimal_clusters: int         # 最优聚类数量
                        - price_trend: str             # 价格趋势分析
                        - buy_threshold: float         # 建议买入阈值
                        - sell_threshold: float        # 建议卖出阈值
                        - stop_loss: float            # 止损价位
                        - confidence: float           # 分析可信度（0-1）
        """
        # 创建API客户端
        api_client = GetCommodityTrendApi(
            device_id=device_info['device_id'],
            device_token=device_info['device_id'],
            auth_token=device_info['uu_token'],
            uk=device_info['uk']
        )
        
        template_api = GetTemplateInfoApi(
            device_id=device_info['device_id'],
            device_token=device_info['device_id'],
            auth_token=device_info['uu_token'],
            uk=device_info['uk']
        )
        
        print(f"开始分析商品 {commodity_name} 的历史数据...")
        
        # 1. 获取所有外观的历史数据
        self.random_sleep()  # 随机等待
        all_history = self.get_all_exterior_history(template_id, api_client, template_api)
        if not all_history:
            print(f"获取商品 {commodity_name} 的历史数据失败")
            return {
                'overall_score': 0,
                'overall_advice': "获取历史数据失败",
                'recommendations': []
            }
            
        # 保存历史数据到数据库
        from com.db.history_data_manager import HistoryDataManager
        history_manager = HistoryDataManager()
        
        # 遍历每个外观的历史数据
        for exterior_name, history_data in all_history.items():
            # 获取磨损值范围
            wear_ranges = {
                "崭新出厂": 0.00,
                "略有磨损": 0.07,
                "久经沙场": 0.15,
                "破损不堪": 0.38,
                "战痕累累": 0.45
            }
            wear_value = wear_ranges.get(exterior_name, 0.00)
            
            # 保存UU历史数据
            if history_data.get('uu_history'):
                history_manager.batch_add_history_data(
                    template_id=history_data['template_id'],
                    his_type=1,  # 1表示UU历史价格
                    wear_value=wear_value,
                    trade_data_list=history_data['uu_history']  # 这里已经是trade_list了
                )
            
            # 保存Steam历史数据
            if history_data.get('steam_history'):
                history_manager.batch_add_history_data(
                    template_id=history_data['template_id'],
                    his_type=2,  # 2表示Steam历史价格
                    wear_value=wear_value,
                    trade_data_list=history_data['steam_history']  # 这里已经是trade_list了
                )
            
            # 保存在售数量历史数据
            if history_data.get('listing_history'):
                history_manager.batch_add_history_data(
                    template_id=history_data['template_id'],
                    his_type=3,  # 3表示在售数量历史
                    wear_value=wear_value,
                    trade_data_list=history_data['listing_history']  # 这里已经是trade_list了
                )
            
        print(f"开始分析商品 {commodity_name} 的价格数据...")
            
        # 2. 分析所有外观的价格
        price_analysis = self.analyze_all_exteriors(all_history)
        if not price_analysis:
            print(f"分析商品 {commodity_name} 的价格数据失败")
            return {
                'overall_score': 0,
                'overall_advice': "分析价格数据失败",
                'recommendations': []
            }
        
        print(f"开始分析商品 {commodity_name} 的价格连续性和波动率...")
        # 3. 分析价格连续性和波动率
        continuity_analysis = self.analyze_price_continuity(all_history, self.wear_ranges)
        
        print(f"开始分析商品 {commodity_name} 的投资价值...")
        # 4. 分析投资价值
        investment_analysis = self.analyze_investment_value(all_history, min_supply=min_supply)
        
        print(f"开始生成商品 {commodity_name} 的投资建议...")
        # 5. 生成投资建议
        advice_text = self.get_investment_advice(investment_analysis)
        
        print(f"开始整理返回数据...")
        # 6. 整理返回数据
        # 计算整体评分
        overall_score = sum(data['investment_score'] for data in investment_analysis.values()) / len(investment_analysis)
        
        # 生成整体建议
        if overall_score >= 70:
            overall_advice = "该饰品具有较高的投资价值，建议关注"
        elif overall_score >= 50:
            overall_advice = "该饰品具有一定投资价值，建议择机介入"
        else:
            overall_advice = "该饰品投资价值一般，建议观望"
            
        # 获取推荐外观列表
        ranked_exteriors = sorted(
            investment_analysis.items(),
            key=lambda x: (x[1]['investment_score'], -x[1].get('price_volatility', 0)),
            reverse=True
        )
        
        # 创建价格分析器实例
        price_analyzer = ItemPricingStrategy()
        
        recommendations = []
        for exterior_name, data in ranked_exteriors:
            if len(recommendations) >= 3:  # 最多取前三名
                break
                
            # 检查在售量是否达到最小要求
            supply = data['supply']
            if supply >= min_supply:
                # 获取该外观的历史交易数据
                exterior_history = all_history[exterior_name]
                
                # 构造正确的数据格式
                trade_data = {
                    'data': {
                        'tradeDataList': exterior_history['uu_history']
                    }
                }
                
                # 分析价格阈值
                price_threshold_analysis = price_analyzer.analyze_price_thresholds(
                    json.dumps(trade_data)
                )
                
                recommendations.append({
                    'name': exterior_name,  # 外观名称
                    'score': data['investment_score'],  # 投资评分
                    'liquidity_score': data['liquidity_score'],  # 流动性评分
                    'price_advantage_score': data['price_advantage_score'],  # 价格优势评分
                    'stability_score': data['stability_score'],  # 稳定性评分
                    'supply_score': data['supply_score'],  # 供需评分
                    'current_price': data['current_price'],  # 当前价格
                    # 'suggested_price': data['suggested_price'],  # 建议买入价格
                    'supply': data['supply'],  # 在售数量
                    'daily_volume': data['daily_volume'],  # 日均成交量
                    'steam_premium': data['steam_premium'],  # Steam溢价率
                    # 'price_trend': data['price_trend'],  # 价格趋势
                    # 'price_vs_avg': (data['avg_price'] - data['current_price']) / data['avg_price'] if data['avg_price'] > 0 else 0,  # 当前价格相对均价的偏离率
                    # 'volatility': data['price_volatility'],  # 价格波动率
                    'template_id': data['template_id'],  # 商品模板ID
                    'price_analysis': price_threshold_analysis  # K-means价格分析结果
                })
        return {
            'overall_score': overall_score,  # 整体评分
            # 'overall_advice': overall_advice,  # 整体建议
            'recommendations': recommendations,  # 推荐外观列表
            # 'advice_text': advice_text  # 详细的投资建议文本
        }

def main():
    """测试入口"""
    # 测试用户信息
    device_info = {
        'device_id': "B90AymoAk2BLsIkIdohIwsqT",
        'device_token': "B90AymoAk2BLsIkIdohIwsqT",
        'uu_token': "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJqdGkiOiJmNTQ3YmMyNWQ5MWU0ZmY3YWU1YzRmNzIyNjVhM2ZmMiIsIm5hbWVpZCI6Ijk1MzQ1OTIiLCJJZCI6Ijk1MzQ1OTIiLCJ1bmlxdWVfbmFtZSI6IuWFqOWkqTgxNTkiLCJOYW1lIjoi5YWo5aSpODE1OSIsInZlcnNpb24iOiJQMUEiLCJuYmYiOjE3Mzg4MzA3OTQsImV4cCI6MTc0MzY3OTk5NCwiaXNzIjoieW91cGluODk4LmNvbSIsImRldmljZUlkIjoiQjkwQXltb0FrMkJMc0lrSWRvaEl3c3FUIiwiYXVkIjoidXNlciJ9.auF2v_ZFr8oHYkcdpCDsAM5Hr0PE5l69yyyMhiMysUo",
        'uk': "5FDFSRFUD0wsn4vgzgeZpQIxPQzgCtMd3SfawJ2FStxg6MCO4d1esVBdyWoCfkr1N"
    }
    
    # 创建分析器实例
    analyzer = PriceAnalyzer()
    
    # 测试商品ID
    template_id = 101453
    
    # 分析投资机会
    result = analyzer.analyze_investment_opportunity(template_id, device_info, min_supply=1000, commodity_name='AK-47 | 红宝石 (崭新出厂)')
    
    # 打印分析结果
    print("\n===== 投资分析结果 =====")
    print(f"整体评分: {result['overall_score']:.1f}")
    # print(f"整体建议: {result['overall_advice']}")
    # print("\n详细建议:")
    # print(result['advice_text'])
    print(f"\n推荐列表:{result['recommendations']}")

if __name__ == "__main__":
    main()